package com.vim.common.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.vim.common.config.WeixinConfig;
import com.vim.common.config.WeixinConstants;
import com.vim.modules.web.model.SysConfig;
import com.vim.modules.web.model.WeixinUser;
import com.vim.modules.web.service.SysConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;

@Component
public class WeixinUtils {

    @Autowired
    private WeixinConfig weixinConfig;

    @Autowired
    private SysConfigService sysConfigService;

    private static WeixinUtils weixinUtils;

    @PostConstruct
    public void init(){
        weixinUtils = this;
        weixinUtils.weixinConfig = this.weixinConfig;
        weixinUtils.sysConfigService = this.sysConfigService;
    }

    /**
     * 获取token
     */
    public static String getToken(){
        String token = "";
        SysConfig findConfig = weixinUtils.sysConfigService.findByCode(WeixinConstants.ACCESS_TOKEN);
        if(null == findConfig){
            token = getServerToken();
            saveToken(token);
        }else{
            JSONObject json = JSONObject.parseObject(findConfig.getConfigValue());
            if(null != json){
                if(isTokenEffective(json.getLong("tokenTime"))){
                    token = json.getString("tokenValue");
                }else {
                    token = getServerToken();
                    updateToken(findConfig.getConfigId(), token);
                }
            }
        }

        return token;
    }
    private static boolean isTokenEffective(Long tokenTime){
        Long currentTime = System.currentTimeMillis();
        if((currentTime - tokenTime)/1000/60/60 < 1.5){
            return true;
        }
        return false;
    }
    private static void saveToken(String tokenValue){
        Map<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("tokenTime", System.currentTimeMillis());
        tokenMap.put("tokenValue", tokenValue);
        SysConfig sysConfig = new SysConfig();
        sysConfig.setConfigName("微信ACCESS_TOKEN");
        sysConfig.setConfigCode(WeixinConstants.ACCESS_TOKEN);
        sysConfig.setConfigValue(JSONObject.toJSONString(tokenMap));
        weixinUtils.sysConfigService.save(sysConfig);
    }
    private static void updateToken(String configId, String tokenValue){
        Map<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("tokenTime", System.currentTimeMillis());
        tokenMap.put("tokenValue", tokenValue);
        SysConfig sysConfig = new SysConfig();
        sysConfig.setConfigId(configId);
        sysConfig.setConfigCode(WeixinConstants.ACCESS_TOKEN);
        sysConfig.setConfigValue(JSONObject.toJSONString(tokenMap));
        weixinUtils.sysConfigService.update(sysConfig);
    }
    private static String getServerToken(){
        Map<String, String> params = new HashMap<>();
        params.put("grant_type", "client_credential");
        params.put("appid", weixinUtils.weixinConfig.getAPPID());
        params.put("secret", weixinUtils.weixinConfig.getAPPSECRET());
        try {
            String str = HttpUtils.sendGet(WeixinConstants.TOKEN_URL, params);
            JSONObject jsonObject = JSONObject.parseObject(str);
            return jsonObject.getString("access_token");
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 更新微信菜单
     */
    public static void createMenuList(String menuStr){
        String url = WeixinConstants.MENU_CREATE_URL.replace("TOKEN", getToken());
        try{
            HttpUtils.sendPostBuffer(url, menuStr);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 获取用户信息
     */
    public static WeixinUser userInfo(String openId){
        try {
            String url = WeixinConstants.USER_INFO_URL.replace("TOKEN", getToken()).replace("OPENID", openId);
            String userinfo = HttpUtils.sendGet(url, new HashMap<>());
            JSONObject jsonResult = JSONObject.parseObject(userinfo);

            if(null != jsonResult){
                WeixinUser user = new WeixinUser();
                user.setNickname(jsonResult.getString("nickname"));
                user.setUserSex(jsonResult.getString("sex"));
                user.setUserAvatar(jsonResult.getString("headimgurl"));
                user.setUserOpenid(jsonResult.getString("openid"));
                user.setUserUnionid(jsonResult.getString("unionid"));
                user.setProvince(jsonResult.getString("province"));
                user.setCity(jsonResult.getString("city"));
                user.setProvince(jsonResult.getString("province"));
                return user;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取用户列表
     */
    public static List<WeixinUser> userlist(String nextOpenid){
        List<WeixinUser> result = new ArrayList<>();
        try {
            String url = WeixinConstants.USER_LIST_URL;
            if(StringUtils.isBlank(nextOpenid)){
                url = url.replace("TOKEN", getToken()).replace("&next_openid=NEXT_OPENID", "");
            }else{
                url = url.replace("TOKEN", getToken()).replace("NEXT_OPENID", nextOpenid);
            }

            JSONObject jsonResult = JSONObject.parseObject(HttpUtils.sendGet(url, new HashMap<>()));
            JSONArray data = jsonResult.getJSONObject("data").getJSONArray("openid");
            Iterator<Object> iterable = data.iterator();
            while (iterable.hasNext()){
                Object openid = iterable.next();
                result.add(userInfo(openid.toString()));
            }

            return result;
        }catch (Exception e){
            e.printStackTrace();
        }

        return null;
    }

}
